// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// S [author] rhyme_lph
// I [email]  rhymelph@gmail.com
// E [github] https://github.com/rhymelph

import 'dart:async';

import 'package:base_plugin/base_plugin.dart';
import 'package:dio/src/response.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/ocr_attachment_entity.dart';
import 'package:finance_app/src/entities/product_entity.dart';
import 'package:finance_app/src/http_service/http_product_service.dart';
import 'package:finance_app/src/mixin/format_group_map_mixin.dart';
import 'package:finance_app/src/mixin/from_attach_mixin.dart';
import 'package:finance_app/src/mixin/refresh_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/provider/dashboard/products_services/products_and_services_provider.dart';
import 'package:finance_app/src/provider/dashboard/products_services/views/products_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/calendar_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/judge_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/text_area_input_bottom_sheet.dart';
import 'package:flutter/material.dart';

class AdjustInventoryListProvider extends BaseProvider<List<ProductEntity>>
    with
        SearchDataListMixin,
        FormatGroupMapLocalMixin<ProductEntity>,
        RefreshMixin<List<ProductEntity>, List<ProductEntity>>,
        FormAttachMixin {
  String currentStatus;
  DateTime date = DateTime.tryParse(Config.currentFY.startDate);
  List<OcrAttachmentEntity> attachedFiles;

  @override
  Future get dataFuture => HttpProductService.productList();

  Map<int, int> numberMap = {};

  @override
  List<ProductEntity> get dataList => data;

  @override
  List<ProductEntity> getFromRequestResult(
      Response<dynamic> result, bool isRefresh) {
    return getEntityFromResult<List<ProductEntity>>(result);
  }

  @override
  Future get refreshFuture => dataFuture;

  @override
  FutureOr<List<ProductEntity>> transformData(
      List<ProductEntity> d, bool isCache) {
    groupMap.clear();
    contactToMap(d);
    return d;
  }

  void updateNumber(int id, int number) {
    numberMap[id] = number;
    update();
  }

  void onAdjust() async {
    obtainContext?.call((context) {
      FocusScope.of(context).requestFocus(FocusNode());
    });
    List products = [];
    for (final item in numberMap.entries) {
      products.add({
        'product_id': item.key,
        'quantity': item.value,
      });
    }
    if (products.length == 0) {
      showToast(S.current.please_update_the_inventory);
      return;
    }
    obtainContext?.call((context) async {
      final isSuccess = await showAdditionalNoteJudgeBottomSheet(context);
      if (isSuccess == null) return;
      String inputInfo = "";
      if (isSuccess == true) {
        inputInfo =
            await showAdjustInventoryInputBottomSheet(context, onDone: (data) {
          Navigator.of(context).pop(data);
        });
      }
      List<ProductEntity> entities;
      List<int> attachmentIds = await uploadFiles();
      if (attachmentIds == null) return;

      await post(
          HttpProductService.productInventoryBatchAdjust(products, inputInfo,
              DateTimeUtils.formatDateTime(date, 'yyyy-MM-dd'), attachmentIds),
          autoHandler: AutoHandler.Toast,
          loadingTip: S.current.loading, onSuccess: (result) {
        entities = getEntityFromResult<List<ProductEntity>>(result);
      });
      if (entities != null) {
        final pro = Providers.get<ProductsAndServicesProvider>(
            RouterGenProviders.productsAndServicesPage, null);
        if (pro != null) {
          pro.getChildProvider<ProductsProvider>().batchUpdate(entities);
        }
        await showAdjustedInventorySuccessBottomSheet(context);
        Navigator.of(context).pop();
        // data = transformData(entities, false);
        // update();
      }
    });
  }

  void onChangeIssueDate() {
    FocusManager.instance.primaryFocus.unfocus();
    obtainContext?.call((context) async {
      date = await showCalendarBottomSheet(context, date);
      update();
    });
  }

  void contactToMap(List<ProductEntity> list) {
    sortGroupToMap(list,
        sort: (a, b) => sortNameFirst(a, b, (t) => t.name),
        group: (a) => groupFirstName(a, (t) => t.name),
        filter: (a) {
          if (a.enableInventory == 0) return false;
          if (currentStatus == 'Active') {
            return a.isActivated == 1;
          }
          if (currentStatus == 'Inactive') {
            return a.isActivated == 0;
          }

          return onFilterSearch(searchController.text, a.name);
        });
  }

  @override
  void searchRefreshData(searchData) {
    transformData(data, false);
    update();
  }

  @override
  List<OcrAttachmentEntity> get attachments => attachedFiles;

  @override
  bool get isEdit => true;
}
